package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.bizsys.domain.*;
import com.ruoyi.bizsys.mapper.*;
import com.ruoyi.bizsys.service.IExtMonnifyReservedAccountsService;
import com.ruoyi.bizsys.service.IExtTryQueueService;
import com.ruoyi.bizsys.service.IRealNameAuthService;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.bizsys.vo.MonnifyReservedAccount;
import com.ruoyi.business.service.ICustVaService;
import com.ruoyi.business.service.IMonnifyService;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.FeishuUtils;
import com.ruoyi.extdata.common.config.PayStackConfig;
import com.ruoyi.extdata.service.IExternalApiService;
import com.ruoyi.system.service.ISysDictTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wqg
 * @date 2022/7/20 11:52 AM
 */
@Service
@Slf4j
public class CustVaServiceImpl implements ICustVaService {

    @Autowired
    ExtMonnifyReservedAccountsMapper extMonnifyReservedAccountsMapper;

    @Autowired
    ExtPaystackReservedAccountsMapper extPaystackReservedAccountsMapper;

    @Autowired
    ExtPaystackCustVaResultMapper extPaystackCustVaResultMapper;

    @Autowired
    IRealNameAuthService realNameAuthService;

    @Autowired
    private AppUserMapper appUserMapper;

    @Autowired
    private ExtResolveAccountMapper extResolveAccountMapper;

    @Autowired
    IExternalApiService externalApiService;

    @Autowired
    PayStackConfig payStackConfig;

    @Autowired
    IExtTryQueueService tryQueueService;

    @Autowired
    private ISysDictTypeService dictTypeService;

    @Autowired
    private IMonnifyService monnifyService;

    @Autowired
    private IExtMonnifyReservedAccountsService extMonnifyReservedAccountsService;

    private static final String EMAIL = "@LCserver.com";

    @Override
    public MonnifyReservedAccount getVaReservedAccount(String custNo) {
        ExtPaystackReservedAccounts extPaystackReservedAccounts = extPaystackReservedAccountsMapper.getOneVa(custNo);
        if (null == extPaystackReservedAccounts) {
            return null;
        }
        MonnifyReservedAccount monnifyReservedAccount = new MonnifyReservedAccount();
        monnifyReservedAccount.setAccountNumber(extPaystackReservedAccounts.getAccountsAccountNumber());
        monnifyReservedAccount.setAccountName(extPaystackReservedAccounts.getAccountsAccountName());
        monnifyReservedAccount.setBankName(extPaystackReservedAccounts.getAccountsBankName());
        monnifyReservedAccount.setBankCode(extPaystackReservedAccounts.getAccountsBankCode());
        return monnifyReservedAccount;
    }

    @Override
    public List<MonnifyReservedAccount> getAllVaReservedAccounts(String custNo) {
        List<MonnifyReservedAccount> monnifyReservedAccounts = new ArrayList<>();
        List<ExtPaystackReservedAccounts> list = extPaystackReservedAccountsMapper.getAllVa(custNo);
        if (null == list) {
            return monnifyReservedAccounts;
        }
        list.stream().forEach(extPaystackReservedAccounts -> {
            MonnifyReservedAccount monnifyReservedAccount = new MonnifyReservedAccount();
            monnifyReservedAccount.setAccountNumber(extPaystackReservedAccounts.getAccountsAccountNumber());
            monnifyReservedAccount.setAccountName(extPaystackReservedAccounts.getAccountsAccountName());
            monnifyReservedAccount.setBankName(extPaystackReservedAccounts.getAccountsBankName());
            monnifyReservedAccount.setBankCode(extPaystackReservedAccounts.getAccountsBankCode());
            monnifyReservedAccounts.add(monnifyReservedAccount);
        });
        return monnifyReservedAccounts;
    }

    @Override
    public void dealMonnifyVaRetry() {
        List<ExtTryQueue> queues = tryQueueService.list(new QueryWrapper<ExtTryQueue>().eq("try_type", ExtTryQueue.VIRTUAL).eq("state", "0").le("try_count", 2));
        queues.forEach(tryTask -> {
            try {
                QueryWrapper<ExtMonnifyReservedAccounts> queryWrapper = new QueryWrapper<ExtMonnifyReservedAccounts>()
                        .eq("cust_no", tryTask.getCustNo())
                        .eq("state", UserConstants.BUSINESS_NORMAL);
                //生成虚拟账户接口
                int count = extMonnifyReservedAccountsMapper.selectCount(queryWrapper);
                if (count < getMonnifySuppertBanks().size()) {
                    delCustVaForMonnify(tryTask.getCustNo());
                } else {
                    //已存在,结束
                    tryQueueService.transferSuccess(tryTask.getSerialNo(), tryTask.getCustNo());
                }
            } catch (BusinessException e) {
                log.error("Monnify VA 重试 异常，custNo = {}, code = {}, errMsg = {}", tryTask.getCustNo(), e.getCode(), e.getDetails());
            } catch (Exception e) {
                log.error("Monnify VA 重试 error，custNo = {}", tryTask.getCustNo(), e);
            }
        });
    }

    /**
     * 处理paystack虚拟账号相关接口重试
     */
    @Override
    public void dealPaystackVaRetry() {
        log.info("dealPaystackForVaRetry::开始处理");
        // 查询 tryType =paystack_create_va 的解析 paramData 获取apiName 进行判断
        List<ExtTryQueue> queues = tryQueueService.list(new QueryWrapper<ExtTryQueue>().eq("try_type", ExtTryQueue.TYPE_PAYSTACK_CREATE_VA).eq("state", "0").gt("try_count", 0));
        if (queues.size() == 0) {
            log.info("dealPaystackForVaRetry::开始处理,queues.size()==0");
            return;
        }
        log.info("dealPaystackForVaRetry::queues.size::" + queues.size());
        queues.forEach(tryTask -> {
            JSONObject paramData = JSON.parseObject(tryTask.getParamData());
            String apiName = paramData.getString("apiName");
            try {
                switch (apiName) {
                    case "Paystack-Create-Customer":
                        dealPaystackCreateCustomerRetry(tryTask);
                        break;
                    case "Paystack-Validate-Customer":
                        dealPaystackValidateCustomerRetry(tryTask);
                        break;
                    case "Paystack-create-va":
                        dealPaystackCreateVaCustomerRetry(tryTask);
                        break;
                    default:
                        break;
                }
            } catch (BusinessException e) {
                log.error("Paystack VA 重试异常，custNo = {}, code = {}，errMsg = {}", tryTask.getCustNo(), e.getCode(), e.getDetails());
            } catch (Exception e) {
                log.error("Paystack VA 重试 error，custNo = {}, code = {}", tryTask.getCustNo(), e.getMessage(), e);
            }

        });
    }

    /**
     * 重试处理CreateVa
     *
     * @param tryTask
     */
    private void dealPaystackCreateVaCustomerRetry(ExtTryQueue tryTask) {
        // 次数需要减掉1次
        tryTask.setTryCount(tryTask.getTryCount() - 1);
        JSONObject paramData = JSON.parseObject(tryTask.getParamData());
        String apiName = paramData.getString("apiName");
        String bankName = paramData.getString("preferred_bank");
        String accountsBankCode = paramData.getString("accounts_bank_code");
        JSONObject apiRes = externalApiService.delPaystackForVaRetry(apiName, paramData.getString("apiUrl"), "POST", paramData);
        log.info("delCustVaForPaystack::重试createVa apiRes:{}", apiRes.toJSONString());
        if (apiRes.getBoolean("status")) {
            ExtPaystackCustVaResult extPaystackCustVaResult = extPaystackCustVaResultMapper.getDetailByCustNo(tryTask.getCustNo());
            insertExtPaystackResAccount(bankName, accountsBankCode, extPaystackCustVaResult, apiRes);
            tryTask.setState("1");//标记结束
        } else {
            if (tryTask.getTryCount() == 0) {
                tryTask.setState("1");//标记结束
                FeishuUtils.sendFeishuToMonit(
                        "DealCustVaServiceImpl", "PaystackVa异常-CreateVa", tryTask.getCustNo(), "", new Exception(apiRes.toJSONString()));
            }
        }
        tryQueueService.updateExtTryQueue(tryTask);
    }

    /**
     * 重试处理Validate
     *
     * @param tryTask
     */
    private void dealPaystackValidateCustomerRetry(ExtTryQueue tryTask) {
        // 次数需要减掉1次
        tryTask.setTryCount(tryTask.getTryCount() - 1);
        JSONObject paramData = JSON.parseObject(tryTask.getParamData());
        String apiName = paramData.getString("apiName");
        JSONObject apiRes = externalApiService.delPaystackForVaRetry(apiName, paramData.getString("apiUrl"), "POST", paramData);
        log.info("delCustVaForPaystack::重试Validate apiRes:{}", apiRes.toJSONString());
        if (apiRes.getBoolean("status")) {
            log.info("delCustVaForPaystack,Validate apiRes:{}，等待webhook通知", apiRes.toJSONString());
            ExtPaystackCustVaResult extPaystackCustVaResult = extPaystackCustVaResultMapper.getDetailByCustNo(tryTask.getCustNo());
            extPaystackCustVaResult.setStatus(ExtPaystackCustVaResult.STATUS_WAIT_WEBHOOK);
            updateExtPaystackCustVaResult(extPaystackCustVaResult);
            tryTask.setState("1");//标记结束
        } else {
            if (tryTask.getTryCount() == 0) {
                tryTask.setState("1");//标记结束
                FeishuUtils.sendFeishuToMonit(
                        "DealCustVaServiceImpl", "PaystackVa异常-Validate", tryTask.getCustNo(), "", new Exception(apiRes.toJSONString()));
            }
        }
        tryQueueService.updateExtTryQueue(tryTask);
    }

    /**
     * 重试处理createCustomer
     *
     * @param tryTask
     */
    private void dealPaystackCreateCustomerRetry(ExtTryQueue tryTask) {
        // 次数需要减掉1次
        tryTask.setTryCount(tryTask.getTryCount() - 1);
        JSONObject paramData = JSON.parseObject(tryTask.getParamData());
        String apiName = paramData.getString("apiName");
        JSONObject apiRes = externalApiService.delPaystackForVaRetry(apiName, paramData.getString("apiUrl"), "POST", paramData);
        log.info("delCustVaForPaystack::重试Create apiRes:{}", apiRes.toJSONString());
        if (apiRes.getBoolean("status")) {
            // create成功，进行Validate
            ExtPaystackCustVaResult extPaystackCustVaResult = extPaystackCustVaResultMapper.getDetailByCustNo(tryTask.getCustNo());
            updateCustVaResAndToValidate(apiRes, extPaystackCustVaResult);
            tryTask.setState("1");//标记结束
        } else {
            if (tryTask.getTryCount() == 0) {
                tryTask.setState("1");//标记结束
                FeishuUtils.sendFeishuToMonit(
                        "DealCustVaServiceImpl", "PaystackVa异常-CreateCustomer", tryTask.getCustNo(), "", new Exception(apiRes.toJSONString()));
            }
        }
        tryQueueService.updateExtTryQueue(tryTask);
    }

    /**
     * 标记流程到 STATUS_VALIDATEING
     *
     * @param apiRes
     * @param extPaystackCustVaResult
     */
    private void updateCustVaResAndToValidate(JSONObject apiRes, ExtPaystackCustVaResult extPaystackCustVaResult) {
        extPaystackCustVaResult.setCustomerCode(apiRes.getJSONObject("data").getString("customer_code"));
        extPaystackCustVaResult.setCustomerId(apiRes.getJSONObject("data").getString("id"));
        extPaystackCustVaResult.setStatus(ExtPaystackCustVaResult.STATUS_VALIDATEING);
        boolean isUpdate = updateExtPaystackCustVaResult(extPaystackCustVaResult);
        if (isUpdate) {
            payStackValidateCustomer(extPaystackCustVaResult);
        }
    }

    /**
     * 处理paystack的VA
     *
     * @param custNo
     */
    @Override
    @Async("threadPoolTaskExecutor")
    public void delCustVaForPaystack(String custNo, String userId) {
        log.info("delCustVaForPaystack:{}", custNo);
        // 先查询extPaystackCustVaResultMapper 查询认证状态
        // 状态0失败，1 成功，2Createing，3 Validateing
        ExtPaystackCustVaResult extPaystackCustVaResult = checkCustVaResulAndBackModel(custNo, userId);
        if (null == extPaystackCustVaResult) {
            log.info("delCustVaForPaystack,custNo:{},未认证成功认证中", custNo);
            return;
        }
        createCustVaForPaystack(extPaystackCustVaResult);
    }

    @Override
    public void createCustVaForPaystack(ExtPaystackCustVaResult extPaystackCustVaResult) {
        log.info("delCustVaForPaystack,custNo:{}，认证成功，查询是否全部银行完成认证", extPaystackCustVaResult.getCustNo());
        // leftjoin查询，字典表在前，用户数据在后，判断那个银行为空就执行那个的操作
        List<ExtPaystackReservedAccounts> list = extPaystackReservedAccountsMapper.getVaList(extPaystackCustVaResult.getCustNo());
        if (0 == list.size()) {
            log.info("delCustVaForPaystack,custNo:{}，认证成功，银行都生成了VA", extPaystackCustVaResult.getCustNo());
            return;
        }
        for (int i = 0; i < list.size(); i++) {
            String bankName = list.get(i).getBankName();
            String accountsBankCode = list.get(i).getAccountsBankCode();
            createDedicatedVA(bankName, accountsBankCode, extPaystackCustVaResult);
        }
    }

    /**
     * 创建当前银行的VA "customer": "CUS_358xertt55", "preferred_bank": "（入参preferred_bank=access-bank/wema-bank）"
     *
     * @param bankName
     * @param extPaystackCustVaResult
     */
    private void createDedicatedVA(String bankName, String accountsBankCode, ExtPaystackCustVaResult extPaystackCustVaResult) {
        log.info("delCustVaForPaystack,custNo:{}，创建当前银行的VA{}", extPaystackCustVaResult.getCustNo(), bankName);
        JSONObject reqParam = new JSONObject();
        reqParam.put("customer", extPaystackCustVaResult.getCustomerCode());
        reqParam.put("preferred_bank", bankName);
        reqParam.put("accounts_bank_code", accountsBankCode);
        JSONObject apiRes = null;
        try {
            apiRes = delHttpToPaystack("Paystack-create-va", payStackConfig.getCreateVa(), reqParam, extPaystackCustVaResult.getCustNo());
            log.info("delCustVaForPaystack,create-va apiRes:{}", apiRes.toJSONString());
            if (apiRes.getBoolean("status")) {
                insertExtPaystackResAccount(bankName, accountsBankCode, extPaystackCustVaResult, apiRes);
            }
        } catch (BusinessException e) {
            log.info("delCustVaForPaystack:发起payStackCreateCustomer失败，进入了轮询");
        }

    }

    private void insertExtPaystackResAccount(String bankName, String accountsBankCode, ExtPaystackCustVaResult extPaystackCustVaResult, JSONObject apiRes) {
        // 插入数据库
        ExtPaystackReservedAccounts extPaystackReservedAccounts = new ExtPaystackReservedAccounts();
        extPaystackReservedAccounts.setCustNo(extPaystackCustVaResult.getCustNo());
        extPaystackReservedAccounts.setCustomerId(extPaystackCustVaResult.getCustomerId());
        extPaystackReservedAccounts.setCustomerCode(extPaystackCustVaResult.getCustomerCode());
        extPaystackReservedAccounts.setAccountsBankName(bankName);
        extPaystackReservedAccounts.setAccountsBankCode(accountsBankCode);
        extPaystackReservedAccounts.setAccountsAccountId(apiRes.getJSONObject("data").getString("id"));
        extPaystackReservedAccounts.setAccountsAccountName(apiRes.getJSONObject("data").getString("account_name"));
        extPaystackReservedAccounts.setAccountsAccountNumber(apiRes.getJSONObject("data").getString("account_number"));
        extPaystackReservedAccounts.setStatus(BizConstants.BIZ_STATUS_1);
        extPaystackReservedAccounts.setState(BizConstants.BIZ_STATUS_1);
        extPaystackReservedAccountsMapper.insert(extPaystackReservedAccounts);
    }

    /**
     * 检查认证是否完成，未完成进行相关流程操作,完成的话返回实体对象
     *
     * @param custNo
     * @return
     */
    private ExtPaystackCustVaResult checkCustVaResulAndBackModel(String custNo, String userId) {
        ExtPaystackCustVaResult extPaystackCustVaResult = extPaystackCustVaResultMapper.getDetailByCustNo(custNo);
        if (null != extPaystackCustVaResult && ExtPaystackCustVaResult.STATUS_SUCCESS == extPaystackCustVaResult.getStatus()) {
            return extPaystackCustVaResult;
        }
        if (null == extPaystackCustVaResult) {
            // 调用创建接口 Create Customer接口 和 Validate Customer
            payStackCreateCustomer(custNo, userId);
            return null;
        }
        if (ExtPaystackCustVaResult.STATUS_CREATEING == extPaystackCustVaResult.getStatus()) {
            // CREATEING 发起 CREATE
            httpCreateCustomer(extPaystackCustVaResult);
            return null;
        }
        if (ExtPaystackCustVaResult.STATUS_VALIDATEING == extPaystackCustVaResult.getStatus()) {
            // VALIDATEING 发起 VALIDATE
            payStackValidateCustomer(extPaystackCustVaResult);
            return null;
        }
        return null;
    }

    /**
     * payStackCreateCustomer
     *
     * @param custNo
     * @param userId
     */
    private void payStackCreateCustomer(String custNo, String userId) {
        AppUser appUser = appUserMapper.selectPhoneByUserId(userId);
        // 下面的联查的，AccountName不是extResolveAccount的是 bank_account的
        ExtResolveAccount extResolveAccount = extResolveAccountMapper.getExtResolveAccountAndBank(custNo);
        // 创建一个createing的数据
        ExtPaystackCustVaResult extPaystackCustVaResultParam = new ExtPaystackCustVaResult();
        extPaystackCustVaResultParam.setCustomerEmail(userId.substring(userId.length() - 10) + EMAIL);
        extPaystackCustVaResultParam.setCustomerPhone(appUser.getPhone());
        extPaystackCustVaResultParam.setCustomerFirstName(extResolveAccount.getAccountName().split(" ")[0]);
        extPaystackCustVaResultParam.setCustomerLastName(extResolveAccount.getAccountName().split(" ")[extResolveAccount.getAccountName().split(" ").length - 1]);
        ExtPaystackCustVaResult extPaystackCustVaResult = createExtPaystackCustVaResult(custNo, appUser, extPaystackCustVaResultParam, extResolveAccount);
        if (null == extPaystackCustVaResult) {
            log.info("delCustVaForPaystack,custNo:{},插入数据库失败", custNo);
            return;
        }
        httpCreateCustomer(extPaystackCustVaResult);
    }

    /**
     * @param extPaystackCustVaResult
     */
    private void httpCreateCustomer(ExtPaystackCustVaResult extPaystackCustVaResult) {
        JSONObject reqParam = new JSONObject();
        reqParam.put("email", extPaystackCustVaResult.getCustomerEmail());
        reqParam.put("phone", extPaystackCustVaResult.getCustomerPhone());
        reqParam.put("first_name", extPaystackCustVaResult.getCustomerFirstName());
        reqParam.put("last_name", extPaystackCustVaResult.getCustomerLastName());
        // 创建一个createing的数据
        JSONObject apiRes = null;
        try {
            apiRes = delHttpToPaystack("Paystack-Create-Customer", payStackConfig.getCreateCustomer(), reqParam, extPaystackCustVaResult.getCustNo());
            log.info("delCustVaForPaystack,Create apiRes:{}", apiRes.toJSONString());
            if (apiRes.getBoolean("status")) {
                // create成功，进行Validate
                updateCustVaResAndToValidate(apiRes, extPaystackCustVaResult);
            }

        } catch (BusinessException e) {
            log.info("delCustVaForPaystack:发起payStackCreateCustomer失败，进入了轮询");
        }
    }

    /**
     * Validate Customer接口认证
     *
     * @param extPaystackCustVaResult
     */
    private void payStackValidateCustomer(ExtPaystackCustVaResult extPaystackCustVaResult) {
        log.info("delCustVaForPaystack发起认证:{}", extPaystackCustVaResult.toString());
        JSONObject reqParam = new JSONObject();
        reqParam.put("country", "NG");
        reqParam.put("type", "bank_account");
        reqParam.put("account_number", extPaystackCustVaResult.getAccountNumber());
        reqParam.put("bank_code", extPaystackCustVaResult.getBankCode());
        reqParam.put("bvn", extPaystackCustVaResult.getBvn());
        reqParam.put("first_name", extPaystackCustVaResult.getCustomerFirstName());
        reqParam.put("last_name", extPaystackCustVaResult.getCustomerLastName());
        log.info("delCustVaForPaystack,Validate param:{}", reqParam.toJSONString());
        JSONObject apiRes = null;
        try {
            apiRes = delHttpToPaystack("Paystack-Validate-Customer", payStackConfig.getValidateCustomer().replace("CUST_CODE", extPaystackCustVaResult.getCustomerCode()), reqParam, extPaystackCustVaResult.getCustNo());
            log.info("delCustVaForPaystack,Validate apiRes:{}", apiRes.toJSONString());
            if (apiRes.getBoolean("status")) {
                log.info("delCustVaForPaystack,Validate apiRes:{}，等待webhook通知", apiRes.toJSONString());
                extPaystackCustVaResult.setStatus(ExtPaystackCustVaResult.STATUS_WAIT_WEBHOOK);
                updateExtPaystackCustVaResult(extPaystackCustVaResult);
            }
        } catch (BusinessException e) {
            log.info("delCustVaForPaystack:发起payStackCreateCustomer失败，进入了轮询");
        }
    }

    private boolean updateExtPaystackCustVaResult(ExtPaystackCustVaResult extPaystackCustVaResult) {
        int update = extPaystackCustVaResultMapper.updateById(extPaystackCustVaResult);
        return 1 == update ? true : false;
    }

    private ExtPaystackCustVaResult createExtPaystackCustVaResult(String custNo, AppUser appUser, ExtPaystackCustVaResult extPaystackCustVaResult, ExtResolveAccount extResolveAccount) {
        QueryWrapper<RealNameAuth> realNameAuthQueryWrapper = new QueryWrapper<>();
        realNameAuthQueryWrapper.eq("cust_no", custNo).eq("state", UserConstants.BUSINESS_NORMAL).select("user_id", "bvn_account", "first_name", "middle_name", "last_name");
        RealNameAuth realNameAuth = realNameAuthService.getOne(realNameAuthQueryWrapper);
        extPaystackCustVaResult.setCustNo(custNo);
        extPaystackCustVaResult.setBvn(realNameAuth.getBvnAccount());
        extPaystackCustVaResult.setCustomerCountry(appUser.getCountryCode());
        extPaystackCustVaResult.setPaystackType("bank_account");
        extPaystackCustVaResult.setAccountNumber(extResolveAccount.getAccountNumber());
        extPaystackCustVaResult.setBankCode(extResolveAccount.getBankCode());
        extPaystackCustVaResult.setState(BizConstants.BIZ_STATUS_1);
        extPaystackCustVaResult.setStatus(ExtPaystackCustVaResult.STATUS_CREATEING);
        int numSuccess = extPaystackCustVaResultMapper.insert(extPaystackCustVaResult);
        if (1 == numSuccess) {
            return extPaystackCustVaResult;
        }
        return null;
    }

    public JSONObject delHttpToPaystack(String apiName, String url, JSONObject reqParam, String custNo) {
        // 下面接口处理了失败的功能 加入重试
        return externalApiService.delPaystackForVa(apiName, url, "POST", reqParam, custNo);
    }

    /**
     * 处理Monnify的VA
     *
     * @param custNo
     */
    @Override
    @Async("threadPoolTaskExecutor")
    public void delCustVaForMonnify(String custNo) {
        log.info("delCustVaForMonnify:{}", custNo);
        // 查询所有monnify账户支持银行
        List<String> monnifySupportBanks = getMonnifySuppertBanks();
        // 查询已经存在的
        List<ExtMonnifyReservedAccounts> monnifyReservedAccounts = extMonnifyReservedAccountsService.list(new QueryWrapper<ExtMonnifyReservedAccounts>()
                .eq("cust_no", custNo)
                .eq("state", UserConstants.BUSINESS_NORMAL)
                .select("cust_no", "bvn", "account_reference", "accounts_account_name", "accounts_account_number", "accounts_bank_name", "accounts_bank_code", "created_on")
                .last("order by id desc"));
        // monnifySupportBanks 去重遍历
        monnifySupportBanks.stream().distinct().forEach(bankCode -> {
            if(monnifyReservedAccounts.size() == 0){
                monnifyService.generateMonnifyReservedAccount(custNo, bankCode);
                return;
            }
            if (!monnifyReservedAccounts.stream().anyMatch(iteam -> iteam.getAccountsBankCode().equals(bankCode))) {
                monnifyService.generateMonnifyReservedAccount(custNo, bankCode);
            }
        });
    }

    private List<String> getMonnifySuppertBanks() {
        List<SysDictData> monnifySuppertBanks = DictUtils.getDictCache(BizConstants.DICT_TYPE_VA_MONNIFY);
        if (CollectionUtils.isEmpty(monnifySuppertBanks)) {
            monnifySuppertBanks = dictTypeService.selectDictDataByType(BizConstants.DICT_TYPE_VA_MONNIFY);
            DictUtils.setDictCache(BizConstants.DICT_TYPE_VA_MONNIFY, monnifySuppertBanks);
        }
        log.info("Monnify 虚拟账户支持银行：{}", monnifySuppertBanks);
        return monnifySuppertBanks.stream().map(SysDictData::getDictValue).collect(Collectors.toList());
    }

}

